package com.jari.lg.service.analysis.parking;

import com.jari.lg.domain.*;
import com.jari.lg.mapper.ParkingDayMapper;
import com.jari.lg.mapper.ParkingInoutRecordDayMapper;
import com.jari.lg.mapper.ParkingInoutRecordTaskResultMapper;
import com.jari.lg.mapper.ParkingMonthMapper;
import com.jari.lg.utils.BaseData;
import com.jari.lg.utils.LogUtil;
import com.jari.lg.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.jari.lg.utils.Utils.*;

/**
 * @author ctl
 * @Description
 * @create 2022-03-23 10:19
 */
@Service
@Slf4j
public class ParkingService {

    private static final Integer PRICE_PER_HOUR = 5;

    @Resource
    private ParkingInoutRecordTaskResultMapper parkingInoutRecordTaskResultMapper;
    @Resource
    private ParkingDayMapper parkingDayMapper;
    @Resource
    private ParkingMonthMapper parkingMonthMapper;
    @Resource
    private ParkingInoutRecordDayMapper parkingInoutRecordDayMapper;

    /**
     * 停车时空分析-列表
     */
    @Scheduled(cron = "0 0 * * * ?")
    public void createParkingInoutRecordTaskResult() {
        try {
            String jobInstanceId = hourFormatterWithoutSep.format(new Date());

            List<ParkingInoutRecordTaskResult> resultList = new ArrayList();
            ParkingInoutRecordTaskResult result = new ParkingInoutRecordTaskResult();
            Date now = new Date();
            Calendar c = Calendar.getInstance();
            c.setTime(now);
            c.add(Calendar.HOUR_OF_DAY, -1);
            for (int i = 0; i < 500; i++) {

                String plateNumber = Utils.createPlateNumber();
                String plateType = Utils.createPlateType();

                result.setJobinstanceid(jobInstanceId);
                result.setPlatenumber(plateNumber);
                result.setPlatetype(plateType);

                Date inDate = new Date(c.getTime().getTime() - (new Random().nextInt(HOURS_IN_DAY) + 10) * SECONDS_IN_HOUR * MILLISECONDS_IN_SECOND);
                Date outDate = new Date(inDate.getTime() + new Random().nextInt(4) * SECONDS_IN_HOUR * MILLISECONDS_IN_SECOND);

                result.setIndate(inDate);
                result.setOutdate(outDate);
                result.setPrice(new Double(Utils.getHoursBetweenDates(outDate, inDate) * PRICE_PER_HOUR));
                result.setDatetime(now);

                resultList.add(result);
                result = new ParkingInoutRecordTaskResult();
            }
            parkingInoutRecordTaskResultMapper.insertBatch(resultList);
        } catch (Exception exception) {
            log.error(LogUtil.getStackMsg(exception));
        }
    }

    /**
     * 停车时空分析-停车收费趋势分析日表
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void createParkingDay() {
        try {
            createParkingDayFromDate(new Date());
        } catch (Exception exception) {
            log.error(LogUtil.getStackMsg(exception));
        }
    }

    /**
     * 根据传入的时间生成停车天表一天数据
     */
    public void createParkingDayFromDate(Date date) {
        try {
            List<ParkingDay> resultList = new ArrayList();
            ParkingDay result = new ParkingDay();

            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);

            for (int i = 0; i < BaseData.parkingLotBaseList.size(); i++) {
                ParkingLotBase parkingLotBase = BaseData.parkingLotBaseList.get(i);
                result.setParkinglotcode(parkingLotBase.getParkingid());
                result.setParkinglotname(parkingLotBase.getParkingname());
                result.setParkinglottype(BaseData.parkingLotTypeList.stream().filter(x->x.getDictdata().equals(parkingLotBase.getParkingtype())).findFirst().get().getDictlabel());

                result.setDatetime(c.getTime());
                result.setParkingcarnum(parkingLotBase.getParkingnum());
                Double turnoverRate = 2 * (new Random().nextDouble() + 1);
                result.setTurnoverrate(turnoverRate);
                Double turnover = turnoverRate * parkingLotBase.getParkingnum() * 1.0;
                result.setTurnover(turnover);
                Integer inCarNum = (int) (turnoverRate * parkingLotBase.getParkingnum());
                result.setIncarnum(inCarNum);
                result.setOutcarnum(inCarNum + new Random().nextInt(30));
                result.setFreecarnum(new Random().nextInt(100));

                resultList.add(result);
                result = new ParkingDay();
            }
            parkingDayMapper.insertBatch(resultList);
        } catch (Exception exception) {
            log.error(LogUtil.getStackMsg(exception));
        }
    }

    /**
     * 按月生成停车天表
     */
    public void batchCreateParkingDayPerMonth(Integer year, Integer month) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);    //month内部是从0开始
        Integer maxDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        //天
        for (int i = 0; i < maxDay; i++) {
            c.set(Calendar.DAY_OF_MONTH, i + 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            Date date = c.getTime();
            createParkingDayFromDate(date);
        }
    }

    /**
     * 停车时空分析-停车收费趋势分析月表
     */
    @Scheduled(cron = "0 0 0 1 1 *")
    public void createParkingMonth() {
        try {
            List<ParkingMonth> resultList = new ArrayList();
            ParkingMonth result = new ParkingMonth();

            Date now = new Date();
            Calendar c = Calendar.getInstance();
            c.setTime(now);
            c.set(Calendar.DAY_OF_MONTH, 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);

            Integer dayNumInMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);

            for (int i = 0; i < BaseData.parkingLotBaseList.size(); i++) {
                ParkingLotBase parkingLotBase = BaseData.parkingLotBaseList.get(i);
                result.setParkinglotcode(parkingLotBase.getParkingid());
                result.setParkinglotname(parkingLotBase.getParkingname());
                result.setParkinglottype(BaseData.parkingLotTypeList.stream().filter(x->x.getDictdata().equals(parkingLotBase.getParkingtype())).findFirst().get().getDictlabel());

                result.setDate(c.getTime());
                result.setParkingcarnum(parkingLotBase.getParkingnum());
                Double turnoverRate = 2 * (new Random().nextDouble() + 1) * dayNumInMonth;
                result.setTurnoverrate(turnoverRate);
                Double turnover = turnoverRate * parkingLotBase.getParkingnum() * 1.0;
                result.setTurnover(turnover);
                Integer inCarNum = (int) (turnoverRate * parkingLotBase.getParkingnum());
                result.setIncarnum(inCarNum);
                result.setOutcarnum(inCarNum + new Random().nextInt(30));
                result.setFreecarnum(new Random().nextInt(100) * dayNumInMonth);

                resultList.add(result);
                result = new ParkingMonth();
            }
            parkingMonthMapper.insertBatch(resultList);
        } catch (Exception exception) {
            log.error(LogUtil.getStackMsg(exception));
        }
    }

    /**
     * 根据传入的时间生成停车天表一月数据
     */
    public void createParkingMonthFromDate(Date date) {
        try {
            List<ParkingMonth> resultList = new ArrayList();
            ParkingMonth result = new ParkingMonth();

            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.set(Calendar.DAY_OF_MONTH, 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);

            Integer dayNumInMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);

            for (int i = 0; i < BaseData.parkingLotBaseList.size(); i++) {
                ParkingLotBase parkingLotBase = BaseData.parkingLotBaseList.get(i);
                result.setParkinglotcode(parkingLotBase.getParkingid());
                result.setParkinglotname(parkingLotBase.getParkingname());
                result.setParkinglottype(BaseData.parkingLotTypeList.stream().filter(x->x.getDictdata().equals(parkingLotBase.getParkingtype())).findFirst().get().getDictlabel());

                result.setDate(c.getTime());
                result.setParkingcarnum(parkingLotBase.getParkingnum());
                Double turnoverRate = 2 * (new Random().nextDouble() + 1) * dayNumInMonth;
                result.setTurnoverrate(turnoverRate);
                Double turnover = turnoverRate * parkingLotBase.getParkingnum() * 1.0;
                result.setTurnover(turnover);
                Integer inCarNum = (int) (turnoverRate * parkingLotBase.getParkingnum());
                result.setIncarnum(inCarNum);
                result.setOutcarnum(inCarNum + new Random().nextInt(30));
                result.setFreecarnum(new Random().nextInt(100) * dayNumInMonth);

                resultList.add(result);
                result = new ParkingMonth();
            }
            parkingMonthMapper.insertBatch(resultList);
        } catch (Exception exception) {
            log.error(LogUtil.getStackMsg(exception));
        }
    }

    /**
     * 按年生成停车月表
     */
    public void batchCreateParkingMonthPerYear(Integer year) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        //月
        for (int i = 0; i < 12; i++) {
            c.set(Calendar.MONTH, i);    //month内部是从0开始
            c.set(Calendar.DAY_OF_MONTH, 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            Date date = c.getTime();
            createParkingMonthFromDate(date);
        }
    }

    /**
     * 停车时空分析-停车收费趋势分析月表
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void createParkingInoutRecordDay() {
        try {
            Date now = new Date();
            createParkingInoutRecordDayFromDate(now);

        } catch (Exception exception) {
            log.error(LogUtil.getStackMsg(exception));
        }
    }


    public void createParkingInoutRecordDayFromDate(Date date){
        List<ParkingInoutRecordDay> resultList = new ArrayList();
        ParkingInoutRecordDay result = new ParkingInoutRecordDay();
        for (int i = 0; i < BaseData.parkingLotBaseList.size(); i++) {
            ParkingLotBase parkingLotBase = BaseData.parkingLotBaseList.get(i);
            Integer recordsNumPerDayAndParkingLot = 5 + new Random().nextInt(100);
            for (int j = 0; j < recordsNumPerDayAndParkingLot; j++) {
                result.setParkinglotcode(parkingLotBase.getParkingid());
                result.setParkinglotname(parkingLotBase.getParkingname());
                result.setPlatenumber(Utils.createPlateNumber());
                result.setDatetime(date);
                result.setIndatetime(new Date(date.getTime() + MILLISECONDS_IN_SECOND * MINUTES_IN_HOUR * new Random().nextInt(12)));
                Integer hour_interval = new Random().nextInt(4) + 1;
                result.setOutdatetime(new Date(result.getIndatetime().getTime() + (long) MILLISECONDS_IN_SECOND * MINUTES_IN_HOUR * (hour_interval)));
                result.setPlatetype(Utils.createPlateType());
                result.setPrice((double) (hour_interval * 4));
                resultList.add(result);
                result = new ParkingInoutRecordDay();
            }
        }
        parkingInoutRecordDayMapper.insertBatch(resultList);
    }

    public void batchCreateParkingInoutRecordDayPerMonth(Integer year, Integer month) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);    //month内部是从0开始
        Integer maxDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        //天
        for (int i = 0; i < maxDay; i++) {
            c.set(Calendar.DAY_OF_MONTH, i + 1);
            c.set(Calendar.HOUR_OF_DAY, 0);
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            Date date = c.getTime();
            createParkingInoutRecordDayFromDate(date);
        }
    }
}

